// Fill out your copyright notice in the Description page of Project Settings.

#include "Isalong2.h"
#include "HoldCustomLogicBase.h"
#include "HoldSwordBase.h"


AHoldSwordBase::AHoldSwordBase()
{
	_tookUpBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TookUpBox"));
	_tookUpBox->AttachTo(_skMesh);
	_tookUpBox->SetCollisionProfileName(TEXT("BuildingTrace"));

	_stMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshOverride"));
	_stMesh->AttachTo(_skMesh);
	_stMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	_stMesh->SetCastShadow(false);

	_fired = true;
}

void AHoldSwordBase::SetUpData(FInteractData* data, int itemType)
{
	Super::SetUpData(data, itemType);

	if (GetRightData()->_staticMeshOverride)
	{
		_stMesh->SetStaticMesh(GetRightData()->_overrideStaticMesh);
		_attackOverlaper->AttachTo(_stMesh, NAME_None, EAttachLocation::SnapToTarget);
		_attackOverlaper->SetBoxExtent(GetRightData()->_preAttackBoxSize);
		_attackOverlaper->SetRelativeLocation(GetRightData()->_preAttackBoxLocation);
		_attackOverlaper->SetRelativeRotation(GetRightData()->_preAttackBoxRotation);
	}
	else
	{
		_skMesh->SetSkeletalMesh(_dataPack->_skeletalMesh);
		_attackOverlaper->AttachTo(_skMesh, NAME_None, EAttachLocation::SnapToTarget);
		_attackOverlaper->SetBoxExtent(GetRightData()->_preAttackBoxSize);
		_attackOverlaper->SetRelativeLocation(GetRightData()->_preAttackBoxLocation);
		_attackOverlaper->SetRelativeRotation(GetRightData()->_preAttackBoxRotation);
	}
	_tookUpBox->SetRelativeLocation(_dataPack->_tookUpBoxLocationOffset);
	_tookUpBox->SetBoxExtent(_dataPack->_tookUpBoxExtent);

	// construct logic
	TArray<UClass*> logics = ((FHoldData*)_dataPack)->_logics;
	for (int i = 0; i < logics.Num(); i++)
	{
		UHoldCustomLogicBase* holdLogicComponent = ConstructObject<UHoldCustomLogicBase>(logics[i], this);
		if (holdLogicComponent)
		{
			holdLogicComponent->RegisterComponent();
			holdLogicComponent->Init(this);
			_holdLogics.Add(holdLogicComponent);
		}
	}
}

FHoldData* AHoldSwordBase::GetRightData()
{
	return (FHoldData*)_dataPack;
}

IWeaponOwner* AHoldSwordBase::GetWeaponOwner()
{
	return _weaponOwner;
}

void AHoldSwordBase::OnFireBegin()
{
	Super::OnFireBegin();

	for (int i = 0; i < _holdLogics.Num(); i++)
	{
		if (_holdLogics[i]->Get_Override_OnFireBegin())
		{
			_holdLogics[i]->OnFireBegin();
			return;
		}
	}

	if (!_fired) { return; }
	if (_dataPack->_characterFireMontage!=nullptr||_dataPack->_characterADSMontage!=nullptr||_dataPack->_weaponFireMontage!=nullptr)
	{
		_fired = false;
	}
	if (_dataPack->_characterFireMontage!=nullptr)
	{
		_weaponOwner->OnPlayMontage(_dataPack->_characterFireMontage);
	}
	if (_dataPack->_fireShake != nullptr&&Cast<ACPlayerCharacter>(_weaponOwner) != nullptr)
	{
		UGameplayStatics::GetPlayerCameraManager(this, 0)->PlayCameraShake(_dataPack->_fireShake);
	}
	if (_dataPack->_weaponFireMontage!=nullptr)
	{
		UAnimInstance* animInstance = _skMesh->GetAnimInstance();
		if (animInstance!=nullptr)
		{
			animInstance->Montage_Play(_dataPack->_weaponFireMontage);
		}
	}
}

void AHoldSwordBase::OnFireEnd()
{
	Super::OnFireEnd();

	for (int i = 0; i < _holdLogics.Num(); i++)
	{
		if (_holdLogics[i]->Get_Override_OnFireEnd())
		{
			_holdLogics[i]->OnFireEnd();
			return;
		}
	}
}

void AHoldSwordBase::OnFireAnimationEnd()
{
	Super::OnFireAnimationEnd();

	for (int i = 0; i < _holdLogics.Num(); i++)
	{
		if (_holdLogics[i]->Get_Override_OnFireAnimationEnd())
		{
			_holdLogics[i]->OnFireAnimationEnd();
			return;
		}
	}

	_fired = true;
}

void AHoldSwordBase::OnFireAnimationFired()
{
	Super::OnFireAnimationFired();

	for (int i = 0; i < _holdLogics.Num(); i++)
	{
		if (_holdLogics[i]->Get_Override_OnFireAnimationFired())
		{
			_holdLogics[i]->OnFireAnimationFired();
			return;
		}
	}

	for (int i=0;i<_preAttackActor.Num();i++)
	{
		// when is hit able object ,do sth fe: call on hurt
		FHitResult hit = _preAttackActor[i];
		FVector phyCenter = GetRightData()->_attackPhysicCenter;
		FVector hitLocation = GetRightData()->_useCustomAttackPhysicCenter ? phyCenter.X*_attackOverlaper->GetForwardVector()+phyCenter.Y*_attackOverlaper->GetRightVector()+phyCenter.Z*_attackOverlaper->GetUpVector()+ _attackOverlaper->GetComponentLocation() : _attackOverlaper->GetComponentLocation();
		IBeHurtable* hurtable = Cast<IBeHurtable>(hit.GetActor());
		if (hurtable!=nullptr)
		{
			hurtable->OnHurt(Cast<AActor>(_weaponOwner), hit.ImpactNormal, hitLocation, _dataPack->_hurtType, _dataPack->_baseHurtValue, hit.GetComponent());
			if (hit.GetComponent() != nullptr&&hit.GetComponent()->IsSimulatingPhysics())
			{
				hit.GetComponent()->AddImpulseAtLocation(10000 * this->GetActorForwardVector(), hitLocation);
			}
		}
		// play fire
	}
}

void AHoldSwordBase::SetupAdditionValue(int val)
{
	SetBulletContains(val, false);
}

void AHoldSwordBase::Tick(float DeltaSeconds)
{
	/*FVector phyCenter = GetRightData()->_attackPhysicCenter;
	FVector hitLocation = GetRightData()->_useCustomAttackPhysicCenter ? phyCenter.X*_attackOverlaper->GetForwardVector() + phyCenter.Y*_attackOverlaper->GetRightVector() + phyCenter.Z*_attackOverlaper->GetUpVector() + _attackOverlaper->GetComponentLocation() : _attackOverlaper->GetComponentLocation();
	DrawDebugSphere(GetWorld(), hitLocation, 5, 20, FColor());
	DrawDebugBox(GetWorld(), _attackOverlaper->GetComponentLocation(), GetRightData()->_preAttackBoxSize, this->GetActorRotation().Quaternion(), FColor());*/
}
